import React, {FC, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState,} from "react";
import {useTranslation} from "react-i18next";
import {Spin, Table} from "antd";
import {AxiosSer} from "@core/services/HttpService";
import {configChange} from "@core/Config";
import {isArray} from "@core/utils";
import "./css/GlobalTable.less";
import {getTableView, getTableViewList} from "../services/ViewService.tsx";
import {treeFilter} from "../utils";

// 配置类型
interface TableConfig {
    pageSize: number;
}

// 表格列定义
interface TableColumn {
    headerName?: string;
    dataIndex?: string;
    key?: string;

    [key: string]: any;
}

// 表格API配置
interface TableApiConfig {
    url: string;
    method?: string;
    initParams?: Record<string, any>;
    treeKey?: string;
}

// 组件属性
interface GlobalTableProps {
    init?: React.RefObject<TableMethods>; // 获取表格对象api
    tableKey?: string; // 表格key
    menuId?: string; // 模块菜单id
    view: string | TableColumn[]; // 表格列头视图
    ds?: Record<string, any>; // 表格数据源配置
    isTreeTable?: boolean; // 是否树形表格
    tableApi: TableApiConfig; // 表格基本属性
    rowKey?: string; // 表格唯一键
    hasCheckbox?: boolean; // 是否有选择框
    height?: number | string; // 表格高度
    dataSource?: any[]; // 表格直接数据
    rowSelection?: 'single' | 'multiple' | 'clickMultiple'; // 行选择类型
    dataSourceFilter?: (data: any[]) => any[]; // 数据过滤方法
    getRowStyle?: (record: any, index: number) => React.CSSProperties; // 控制行样式功能
    isRowSelectable?: (record: any, index: number) => boolean; // 控制行不可选中功能
    onSelectChange?: (selectedRows: any[]) => void; // 数据选中方法
    onCellDoubleClicked?: (record: any) => void; // 单元格双击方法
    getLinkParams?: (record: any) => Record<string, any>; // 链接参数方法
    className?: string; // 自定义类名
}

// 表格方法
interface TableMethods {
    searchTable: (params: Record<string, any>) => void;
    getTableSelectedRows: () => any[];
    getTableAllRows: () => any[];
    refresh: () => void;
}

// 分页信息
interface PaginationInfo {
    current: number;
    pageSize: number;
    total?: number;
}

// 排序信息
interface SorterInfo {
    field?: string;
    order?: 'ascend' | 'descend' | null;
}

// 过滤信息
interface FilterInfo {
    [key: string]: any;
}

let pageSize: number;

configChange((config: TableConfig) => {
    pageSize = config.pageSize;
});

const GlobalTable: FC<GlobalTableProps> = (props) => {
    const {
        init,
        tableKey,
        menuId,
        view,
        ds = {},
        isTreeTable = false,
        tableApi,
        rowKey = "id",
        hasCheckbox = false,
        height,
        dataSource: externalDataSource,
        rowSelection = 'multiple',
        dataSourceFilter,
        getRowStyle,
        isRowSelectable,
        onSelectChange,
        onCellDoubleClicked,
        getLinkParams,
        className = "",
    } = props;

    const {t} = useTranslation();
    const [loading, setLoading] = useState<boolean>(false);
    const [columns, setColumns] = useState<TableColumn[]>([]);
    const [dataSource, setDataSource] = useState<any[]>([]);
    const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
    const [total, setTotal] = useState<number>(0);
    const [pagination, setPagination] = useState<PaginationInfo>({
        current: 1,
        pageSize,
    });
    const [sorter, setSorter] = useState<SorterInfo>({});
    const [filters, setFilters] = useState<FilterInfo>({});

    const searchParamsRef = useRef<Record<string, any>>({});
    const abortControllerRef = useRef<AbortController | null>(null);

    // 获取当前表格唯一键属性
    const getKey = useCallback((record: any) => {
        if (typeof rowKey === 'function') {
            return rowKey(record);
        }
        return record[rowKey] || record.key || record.id;
    }, [rowKey]);

    // 取消进行中的请求
    const cancelPendingRequests = useCallback(() => {
        if (abortControllerRef.current) {
            abortControllerRef.current.abort();
            abortControllerRef.current = null;
        }
    }, []);

    // 加载列配置
    const loadView = useCallback(async () => {
        try {
            let res: { columns: TableColumn[] } = {columns: []};

            if (isArray(view)) {
                if (view[0]?.headerName) {
                    res.columns = view as TableColumn[];
                } else {
                    res.columns = await getTableViewList(
                        {containColumns: view},
                        {...ds, getLinkParams}
                    );
                }
            } else {
                res = await getTableView(view, {...ds, getLinkParams});
            }

            setColumns(res.columns);
        } catch (error) {
            console.error("Failed to load table view:", error);
        }
    }, [view, ds, getLinkParams]);

    // 加载表格数据
    const loadTableData = useCallback(async (params: Record<string, any> = {}) => {
        // 如果有外部数据源，直接使用
        if (externalDataSource) {
            setDataSource(externalDataSource);
            setTotal(externalDataSource.length);
            return;
        }

        // 取消之前的请求
        cancelPendingRequests();

        setLoading(true);
        const {url, method = "get", initParams = {}} = tableApi;

        if (!url) {
            setLoading(false);
            return;
        }

        try {
            // 创建新的AbortController
            abortControllerRef.current = new AbortController();

            const requestParams = {
                ...initParams,
                ...searchParamsRef.current,
                ...params,
            };

            const response = await AxiosSer(
                url,
                method,
                requestParams,
                {signal: abortControllerRef.current.signal}
            );

            let {data = [], records} = response;

            if (!isArray(data)) {
                data = [data];
            }

            // 应用数据过滤
            const filteredData = dataSourceFilter ? dataSourceFilter(data) : data;

            setTotal(records || filteredData.length);
            setDataSource(filteredData);
        } catch (error: any) {
            if (error.name === 'AbortError') {
                console.log('Request aborted');
            } else {
                console.error("Failed to load table data:", error);
            }
        } finally {
            setLoading(false);
            abortControllerRef.current = null;
        }
    }, [tableApi, externalDataSource, dataSourceFilter, cancelPendingRequests]);

    // 刷新表格数据
    const refreshTable = useCallback(() => {
        loadTableData({
            page: pagination.current,
            rows: pagination.pageSize,
            sidx: sorter.field,
            sord: sorter.order === 'ascend' ? 'asc' : 'desc',
            ...filters,
        });
    }, [loadTableData, pagination, sorter, filters]);

    // 格式化树形数据
    const formatTreeData = useCallback((data: any[]) => {
        const {treeKey = "children"} = tableApi || {};


        return data.map(item => {
            let children = [];
            if (item[treeKey]) {
                children = formatTreeData(item[treeKey]) || []
            }
            return {
                ...item,
                key: getKey(item),
                children: children.length > 0 ? children : undefined,
            }
        });
    }, [tableApi, getKey]);

    // 行选择处理
    const handleSelectChange = useCallback((newSelectedRowKeys: React.Key[]) => {
        setSelectedRowKeys(newSelectedRowKeys);

        if (onSelectChange) {
            const selectedRows = dataSource.filter(item =>
                newSelectedRowKeys.includes(getKey(item))
            );
            onSelectChange(selectedRows);
        }
    }, [dataSource, onSelectChange, getKey]);

    // 表格变化处理（分页、排序、筛选）
    const handleTableChange = useCallback((
        newPagination: any,
        newFilters: any,
        newSorter: any
    ) => {
        // 更新状态
        setPagination({
            current: newPagination.current || 1,
            pageSize: newPagination.pageSize || pageSize,
        });

        setSorter({
            field: newSorter.field,
            order: newSorter.order,
        });

        setFilters(newFilters);

        // 准备请求参数
        const params: Record<string, any> = {
            page: newPagination.current,
            rows: newPagination.pageSize,
        };

        // 添加排序参数
        if (newSorter.field && newSorter.order) {
            params.sidx = newSorter.field;
            params.sord = newSorter.order === 'ascend' ? 'asc' : 'desc';
        }

        // 添加过滤参数
        Object.keys(newFilters).forEach(key => {
            if (newFilters[key]) {
                params[key] = newFilters[key];
            }
        });

        // 加载数据
        loadTableData(params);
    }, [loadTableData]);

    // 行双击处理
    const handleRowDoubleClick = useCallback((record: any) => {
        onCellDoubleClicked && onCellDoubleClicked(record);
    }, [onCellDoubleClicked]);

    // 初始化
    useEffect(() => {
        loadView();
        refreshTable();

        // 清理函数
        return () => {
            cancelPendingRequests();
        };
    }, []);

    // 当外部数据源变化时更新
    useEffect(() => {
        if (externalDataSource) {
            const filteredData = dataSourceFilter
                ? dataSourceFilter(externalDataSource)
                : externalDataSource;
            setDataSource(filteredData);
            setTotal(filteredData.length);
        }
    }, [externalDataSource, dataSourceFilter]);

    // 暴露API
    useImperativeHandle(init, () => ({
        searchTable: (params: Record<string, any>) => {
            searchParamsRef.current = {...params};
            refreshTable();
        },
        getTableSelectedRows: () => {
            return treeFilter(dataSource, (item) => {
                return selectedRowKeys.includes(getKey(item))
            });
        },
        getTableAllRows: () => [...dataSource],
        refresh: refreshTable,
    }));

    // 处理行选择配置
    const rowSelectionConfig = useMemo(() => {
        if (!hasCheckbox && rowSelection === 'multiple') {
            return undefined;
        }

        const baseConfig = {
            selectedRowKeys,
            onChange: handleSelectChange,
            getCheckboxProps: isRowSelectable ? (record: any) => ({
                disabled: !isRowSelectable(record, dataSource.indexOf(record)),
            }) : undefined,
        };

        if (rowSelection === 'single') {
            return {
                type: 'radio',
                ...baseConfig,
            };
        }

        return {
            type: 'checkbox',
            ...baseConfig,
        };
    }, [hasCheckbox, rowSelection, selectedRowKeys, handleSelectChange, isRowSelectable, dataSource]);

    // 处理分页配置
    const paginationConfig = useMemo((): false | TablePaginationConfig => {
        if (isTreeTable || externalDataSource) {
            return false;
        }

        return {
            ...pagination,
            total,
            showSizeChanger: true,
            showQuickJumper: true,
            showTotal: (total, range) =>
                t('globalTable.showTotal', {
                    range0: range[0],
                    range1: range[1],
                    total
                }),
            pageSizeOptions: ['10', '20', '50', '100'],
        };
    }, [isTreeTable, externalDataSource, pagination, total, t]);

    // 处理表格数据
    const processedDataSource = useMemo(() => {
        if (isTreeTable) {
            return formatTreeData(dataSource);
        }
        return dataSource.map(item => ({
            ...item,
            key: getKey(item),
        }));
    }, [dataSource, isTreeTable, formatTreeData, getKey]);

    // 处理行样式
    const getRowClassName = useCallback((record: any, index: number): string => {
        const classes = [];

        if (getRowStyle) {
            // 如果有自定义行样式逻辑，可以在这里添加类名
            const style = getRowStyle(record, index);
            if (style && style.className) {
                classes.push(style.className);
            }
        }

        // 添加交替行样式
        if (index % 2 === 0) {
            classes.push('global-table-row-even');
        } else {
            classes.push('global-table-row-odd');
        }

        return classes.join(' ');
    }, [getRowStyle]);
    return (
        <Spin
            spinning={loading}
            wrapperClassName={`global-table-container ${className}`}
            tip={t('globalTable.loading')}
        >
            <Table
                key={tableKey}
                columns={columns}
                dataSource={processedDataSource}
                rowKey={rowKey}
                loading={loading}
                pagination={paginationConfig}
                onChange={handleTableChange}
                rowSelection={rowSelectionConfig}
                onRow={(record, index) => ({
                    onDoubleClick: () => handleRowDoubleClick(record),
                    style: getRowStyle ? getRowStyle(record, index || 0) : undefined,
                    className: getRowClassName(record, index || 0),
                })}
                scroll={{
                    y: height ? height : 400,
                    x: 'max-content',
                }}
                size="middle"
                className="global-table"
            />
        </Spin>
    );
};

export default React.memo(GlobalTable);